
#include <iostream>
using namespace std;
int Bits(int m, int n, int c){return ((c >> n) & ~(-2 << (m - n)));}
int D(int x){return ((x == 0x2F) ? 0x3F : ((x == 0x2B) ? 0x3E : ((x <= 0x39) ? (x + 0x4) : ((x <= 0x5A) ? (x - 0x41) : (x - 0x47)))));}

char* Base64Decoder(const char* input, int len){
    char* output = new char[(len * 1) + 0];
    int r0 = 0;int state = 0;
    int pos = 0;
    for (int i = 0; i < len; i++){
        int c = (int)input[i];
        switch (state){
        case (0): {
            if (((!(c==0x2B)&&((0x2F>c)||!(Bits(15,6,c)==0)||(Bits(5,0,c)>0x39))&&!(c==0x3D)&&((0x41>c)||!(Bits(15,7,c)==0)||(Bits(6,0,c)>0x5A))&&((0x61>c)||!(Bits(15,7,c)==0)||(Bits(6,0,c)>0x7A)))||(c==0x3D)||((c==0x3D)&&!(r0==0)))) {
                throw ("InvalidInput");
            } else {
                r0 = (Bits(13,0,D(c))<<2);state = 1;
            }
            break;}
        case (1): {
            if (((!(c==0x2B)&&((0x2F>c)||!(Bits(15,6,c)==0)||(Bits(5,0,c)>0x39))&&!(c==0x3D)&&((0x41>c)||!(Bits(15,7,c)==0)||(Bits(6,0,c)>0x5A))&&((0x61>c)||!(Bits(15,7,c)==0)||(Bits(6,0,c)>0x7A)))||(c==0x3D)||((c==0x3D)&&!(r0==0)))) {
                throw ("InvalidInput");
            } else {
                output[pos++] = ((char)(r0|Bits(5,4,D(c))));r0 = (Bits(3,0,D(c))<<4);state = 2;
            }
            break;}
        case (2): {
            if (((!(c==0x2B)&&((0x2F>c)||!(Bits(15,6,c)==0)||(Bits(5,0,c)>0x39))&&!(c==0x3D)&&((0x41>c)||!(Bits(15,7,c)==0)||(Bits(6,0,c)>0x5A))&&((0x61>c)||!(Bits(15,7,c)==0)||(Bits(6,0,c)>0x7A)))||((c==0x3D)&&!(r0==0)))) {
                throw ("InvalidInput");
            } else {
                if ((c==0x3D)) {r0 = 0;state = 3;} else {output[pos++] = ((char)(r0|Bits(5,2,D(c))));r0 = (Bits(1,0,D(c))<<6);state = 4;}
            }
            break;}
        case (4): {
            if (((!(c==0x2B)&&((0x2F>c)||!(Bits(15,6,c)==0)||(Bits(5,0,c)>0x39))&&!(c==0x3D)&&((0x41>c)||!(Bits(15,7,c)==0)||(Bits(6,0,c)>0x5A))&&((0x61>c)||!(Bits(15,7,c)==0)||(Bits(6,0,c)>0x7A)))||((c==0x3D)&&!(r0==0)))) {
                throw ("InvalidInput");
            } else {
                if ((c==0x3D)) {r0 = 0;state = 5;} else {output[pos++] = ((char)(r0|D(c)));r0 = 0;state = 0;}
            }
            break;}
        case (5): {
            throw ("InvalidInput");
            break;}
        case (3): {
            if (((!(c==0x2B)&&((0x2F>c)||!(Bits(15,6,c)==0)||(Bits(5,0,c)>0x39))&&!(c==0x3D)&&((0x41>c)||!(Bits(15,7,c)==0)||(Bits(6,0,c)>0x5A))&&((0x61>c)||!(Bits(15,7,c)==0)||(Bits(6,0,c)>0x7A)))||((c==0x3D)&&!(r0==0))||!(c==0x3D))) {
                throw ("InvalidInput");
            } else {
                r0 = 0;state = 5;
            }
            break;}
        default: {
            throw ("Base64Decoder");
                 }
        }
    }
    switch (state){
    case (0): {

        break;}
    case (1): {
        throw ("InvalidInput");
        break;}
    case (2): {
        throw ("InvalidInput");
        break;}
    case (4): {
        throw ("InvalidInput");
        break;}
    case (5): {

        break;}
    case (3): {
        throw ("InvalidInput");
        break;}
    default: {
        throw ("Base64Decoder");
             }
    }
    return output;
}
